package org.cnbi.service.impl;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.cnbi.dao.IHandleDao;
import org.cnbi.entity.IndicatorExpression;
import org.cnbi.entity.Kemu;
import org.cnbi.service.IComposeService;
import org.cnbi.utils.date.DateUtil;
import org.cnbi.utils.exception.BusinessException;
import org.cnbi.utils.expression.ExpressionParserUtil;
import org.cnbi.utils.pojo.indicator.IndicatorDimBean;
import org.cnbi.utils.pojo.indicator.IndicatorParamsBean;
import org.cnbi.utils.pojo.indicator.ItemUtil;
import org.cnbi.utils.pojo.kemu.KemuParams;
import org.cnbi.utils.pojo.kemu.ReplaceParam;
import org.cnbi.utils.string.StringUtil;
import org.cnbi.utils.tools.Constants;
import org.cnbi.utils.tools.MenuConstants;
import org.cnbi.utils.tools.SymbolConstants;
import org.cnbi.web.controller.base.BaseController;
import org.cnbi.web.utils.ContextHolderUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
/**
 * Copyright © 2014中国经邦. All rights reserved.
 * @author 龚佳新
 * @date 2014年5月10日下午3:57:07
 * @cnbi-web
 */
@Service("composeService")
public class IComposeServiceImpl implements IComposeService {
	
	protected static  final Log logger = LogFactory.getLog(IComposeServiceImpl.class);
	
	@Autowired
	private IHandleDao handleDao;
	
	/**
	 *  对公式进行解析拆分成一数组
	 *  @param formular = Fact("0001","${company},0&0,1200100","C")
	 *                        主题0001   公司100110  期间2013&1  项目1011  度量B
	 *  @return
	 */
	public  String[] getFactFomularArray(String formular) {
		Pattern pat = Pattern.compile("\\(.*?\\)");
		Matcher mat = pat.matcher(formular);
		if (mat.find()) {
			formular = mat.group(0).substring(1, mat.group(0).length() - 1);
		}
		return formular.replace("\"", "").split("\\,");

	}
	@Cacheable(value = "locationSearchCache", key = "#queryParam.cacheKey")
	@Override
	public IndicatorExpression queryIndicatorList(Map<String,String> sqlMap,IndicatorDimBean queryParam) {
		IndicatorExpression indicatorBean =  queryParam.getIndicatorBean();
		List<IndicatorParamsBean> copyList = indicatorBean.getParams();
		String expression = indicatorBean.getExp();
		 List<IndicatorParamsBean> params=new ArrayList<IndicatorParamsBean>(Arrays.asList(new IndicatorParamsBean[copyList.size()]));
	    java.util.Collections.copy(params, copyList);
	    for (IndicatorParamsBean param : params) {
			String[] factArr = getFactFomularArray(param.getExp());
			String period = DateUtil.getRelativePeriod(factArr[2], queryParam.getPeriod());
			String sql = sqlMap.get(factArr[0]);
			if(StringUtil.isBlank(sql)){
				System.out.println(param.getExp());
				logger.error("主题编码为"+factArr[0]+"】的没有找到指标运算sql模板！请检查配制！");
				return null;
			}
			ItemUtil queryItem =  new ItemUtil(factArr[3],Constants.FACT+SymbolConstants.UNDERLINE+factArr[4],queryParam.getCompany(),period);
			BigDecimal datas =handleDao.queryBigDicamal(sql,queryItem);
			 param.setDatas(datas);
			 String value = datas.toString();
			 if(datas.floatValue()<0){
				 value = "("+value+")";
			 }
			  expression = expression.replace(param.getName(),value);
			  param = (IndicatorParamsBean)param.clone();
			  logger.warn("查出"+queryItem.getPeriod()+"参数=="+param.getName()+"===="+datas+"---->内存地址为===="+param.toString()+"----cache=="+queryItem.getCacheKey());
			// System.out.println(param.getName()+param.toString());
		}
		indicatorBean.setParams(params);
	    try {
			double datas = ExpressionParserUtil.calculateNumber(expression);
			indicatorBean.setDatas(datas);
			indicatorBean.setFun(expression);
			logger.warn(indicatorBean.getName()+queryParam.getPeriod()+"---exp==after>>>>>"+expression+"=="+datas);
		} catch (Exception e) {
			throw new BusinessException("查询"+indicatorBean.getName()+indicatorBean.getId()+"==="+expression+"===指标时出错了！ \n"+e.getMessage());
		}
	    logger.info("成功缓存了key="+queryParam.getCacheKey()+"数据 ");
		return indicatorBean;
	}
	

	@Override
	public int queryKemuLevel(String sql) {
		int nlevel = 0;
		try {
			@SuppressWarnings("unchecked")
			List<Kemu> kemu = (List<Kemu>) handleDao.query(sql, new Kemu());
			if(kemu.size() != 0){
				nlevel = kemu.get(0).getNlevel();
			}
		} catch (Exception e) {
			throw new BusinessException("执行..查询[科目级次]..."+sql+e.getMessage());
		}
		return nlevel;
	}
	
	//@Cacheable(value = "locationSearchCache", key = "#queryParam.cacheKey")
	@Override
	public Map<String,Object> queryKemuList(String sql, KemuParams queryParams,boolean boo) {
		Map<String,Object> map = new HashMap<String,Object>();
		//度量要特殊处理
		String[] measure =  queryParams.getMeasure();
		String[] kemu = queryParams.getKemu();
		String[] period =queryParams.getPeriod();
		ReplaceParam param = new ReplaceParam();
		param.setCompany(StringUtil.getArraytoSting(queryParams.getCompany(),null,null,null));
		param.setPeriod(StringUtil.getArraytoSting(period,null,null,null));
		param.setAccount(StringUtil.getArraytoSting(kemu, null, null, null));
		param.setMeasure(StringUtil.getArraytoSting(measure, Constants.FACT, null, SymbolConstants.UNDERLINE));
		//List<DynamicBean> list = new ArrayList<DynamicBean>();
		List<Map> list = new ArrayList<Map>(); 
		String[] label = null;
		if(boo){		
			String var  = "maxcase";
			String	maxcase = ContextHolderUtils.getSqlByKey(MenuConstants.KEMU+var);
			String rang = "";
			for (int i = 0; i < period.length; i++) {
				rang += maxcase.replaceAll(":period", "'"+period[i]+"'");
				if(measure.length < 2){
					rang = rang.replace(":dim", param.getMeasure());
				}
				if(i != period.length -1){
					rang += ",";
				}
			}
			sql = sql.replace(":maxcase", rang).replace(":measure", "a." + param.getMeasure());
		}
		
		try {
			//list = handleDao.queryDynamicBeanList(sql, param);
			list = handleDao.queryListMapBean(sql, param);
			label = getNameList(list,label);
		} catch (Exception e) {
			throw new BusinessException("执行..查询[科目数据]..."+sql+e.getMessage());
		}
		map.put("label", label);
		map.put(Constants.DATAS, list);
		return map;
	}
	
	private String[] getNameList(List<Map> list,String[] label) {
		for (int i = 0; i < list.size(); i++) {
			Map map  = list.get(i);
			Set<String> set =  map.keySet();
			Iterator<String> iter = set.iterator();
			if(i == 0)
				label = new String[set.size()];
			int k = 0;
			while(iter.hasNext()){
				String colName = iter.next();
				if(i == 0){
					label[k] = colName;
					k++;
				}
				if(colName.equals("company")){;
					map.put(colName,ContextHolderUtils.getCompany((String)map.get(colName)).getSname());
				}else if(colName.equals("account")){
					map.put(colName, BaseController.getAccountNameByScode((String)map.get(colName)));
				}else if(colName.equals("period")){
					map.put(colName, StringUtil.getPeriodName((String)map.get(colName)));
				}
			}
		}
		return label;
	}
}
